home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1995-05-24 | 13.3 KB | 405 lines | [ TEXT/MPCC]
/* File: QTInternals.c Contains: Functions dealing with dumping internal movie information. Written by: DTS Copyright: © 1995 by Apple Computer, Inc., all rights reserved. Change History (most recent first): <1> 1/4/95 khs first file */ // INCLUDES #include "QTInternals.h" #include "DTSQTUtilities.h" // ______________________________________________________________________ // FUNCTIONS // ______________________________________________________________________ void ShowGlobalMovieInfo(Movie theMovie) { OSErr anErr = noErr; Str255 tmpStr; TimeValue tv, ts; Fixed mr; long movieSize = 0L; DebugAssert(aMovie != NULL); GetWTitle(FrontWindow(), tmpStr); printf("\nGlobal System Information for %s:\n", p2cstr(tmpStr)); // Memory related information. anErr = QTUCalculateMovieMemorySize(theMovie, &movieSize); if(anErr == noErr) { printf("This movie allocates %ld bytes in the current application heap.\n", movieSize); printf("Note that any possible associated movie controllers take each 10k or so.\n\n"); } // Global Time Information ts = GetMovieTimeScale(theMovie); tv = GetMovieDuration(theMovie); printf("The time scale for this movie is %ld.\n", ts); printf("The movie duration (TimeValue) = %ld\n", tv); printf("The movie duration in seconds = %7.2f\n", (float) tv / ts); printf("The current movie position (in seconds) = %7.2f\n", (float) GetMovieTime(theMovie, NULL) / ts); mr = GetMovieRate(theMovie); printf("The current movie rate is %7.2f (0 means movie is not running, < 0 going backwards).\n", (float) mr /fixed1); } // ______________________________________________________________________ void ShowMovieTrackInfo(Movie theMovie) { OSErr anErr = noErr; long aTrackCount, index; Track aTrack; long aTrackUsage; Str255 tmpStr; Fixed height, width; short trackVol; MatrixRecord mr; long nVideoTracks = 0; long nSoundTracks = 0; long nTextTracks = 0; long nMusicTracks = 0; GetWTitle(FrontWindow(), tmpStr); printf("\nTrack Information for %s:\n", p2cstr(tmpStr)); // TRACK COUNT aTrackCount = GetMovieTrackCount(theMovie); anErr = GetMoviesError(); DebugAssert(anErr == noErr); if(anErr != noErr) return; if(aTrackCount == 0) { printf("The Movie has no tracks.\n"); return; } else printf("The Movie has %d track(s).\n", aTrackCount); // Parse through each track and get more information: for(index = 1; index <= aTrackCount; index++) { OSType aTrackType; Media aMedia; printf("\n"); aTrack = GetMovieIndTrack(theMovie, index); // TRACK TYPE aMedia = GetTrackMedia(aTrack); GetMediaHandlerDescription(aMedia, &aTrackType, 0, 0); switch (aTrackType) { case SoundMediaType: printf("This is a sound track.\n"); nSoundTracks++; break; case VideoMediaType: printf("This is a video track.\n"); nVideoTracks++; break; case TextMediaType: printf("This is a text track.\n"); nTextTracks++; break; case MPEGMediaType: printf("This is an MPEG track.\n"); break; case MusicMediaType: printf("This is a music track.\n"); nMusicTracks++; break; case TimeCodeMediaType: printf("This is a time code track.\n"); break; default: { Byte *bp = (Byte *)&aTrackType; printf("The track is of type '%c%c%c%c' format.\n", bp[0], bp[1], bp[2], bp[3]); break; } } // TRACK ID printf("Track ID: %d\n", GetTrackID(aTrack)); // TRACK ENABLED if(GetTrackEnabled(aTrack)) printf("Track is enabled.\n"); else printf("Track is disabled.\n"); // TRACK LAYER printf("Track Layer: %d\n", GetTrackLayer(aTrack)); // TRACK USAGE aTrackUsage = GetTrackUsage(aTrack); if(aTrackUsage & trackUsageInMovie) printf("Track is used in Movie.\n"); if(aTrackUsage & trackUsageInPreview) printf("Track is used in a preview.\n"); if(aTrackUsage & trackUsageInPoster) printf("Track is used in a poster.\n"); // TRACK DURATION printf("Duration of the track = %ld\n", GetTrackDuration(aTrack)); // TRACK DIMENSIONS GetTrackDimensions(aTrack, &width, &height); printf("Track width = %ld, Track height = %ld\n", Fix2Long(width), Fix2Long(height)); // TRACK MATRIX GetTrackMatrix(aTrack, &mr); printf("Matrix record, row 0 = [%ld], [%ld], [%ld]\n", Fix2Long(*mr.matrix[0,0]), Fix2Long(*mr.matrix[0,1]), Fix2Long(*mr.matrix[0,2])); printf("Matrix record, row 1 = [%ld], [%ld], [%ld]\n", Fix2Long(*mr.matrix[1,0]), Fix2Long(*mr.matrix[1,1]), Fix2Long(*mr.matrix[1,2])); printf("Matrix record, row 2 = [%ld], [%ld], [%ld]\n", Fix2Long(*mr.matrix[2,0]), Fix2Long(*mr.matrix[2,1]), Fix2Long(*mr.matrix[2,2])); // TRACK VOLUME trackVol = GetTrackVolume(aTrack); if(trackVol == 255) printf("Track Volume is 1.0\n"); else printf("Track Volume = %d.%d\n", (signed short)(trackVol >> 8) , (trackVol & 0xFF)); } // Check how many similar tracks, if too many of same warn (crossplatform issues) if(nVideoTracks > 1) printf("NOTE! You have more than one video track (%ld tracks), this will be a problem with QuickTime for Windows.\n", nVideoTracks); if(nSoundTracks > 1) printf("NOTE! You have more than one sound track (%ld tracks), you need to enable just one at a time under QuickTime for Windows (2.0.1 forward).\n", nSoundTracks); if(nTextTracks > 1) printf("NOTE! You have more than one text track (%ld tracks), this will be a problem with QuickTime for Windows.\n", nTextTracks); if(nMusicTracks > 1) printf("NOTE! You have more than one music track (%ld tracks), this will be a problem with QuickTime for Windows.\n", nMusicTracks); } // ______________________________________________________________________ void ShowMovieVideoInfo(Movie theMovie) { OSErr anErr = noErr; Str255 tmpStr; short trackCount, index; long nSamples; float nSeconds; DebugAssert(aMovie != NULL); GetWTitle(FrontWindow(), tmpStr); printf("\nVideo Media Information for %s:\n", p2cstr(tmpStr)); // VIDEO FRAMES/SAMPLES nSamples = QTUCountMediaSamples(theMovie, VideoMediaType); printf("The movie has %ld video frames (samples) ", nSamples); printf("of which %ld are key frames\n", QTUCountKeySamples(theMovie, VideoMediaType) ); printf("The duration of the first video sample is %ld\n", QTUGetDurationOfFirstMovieSample(theMovie, VideoMediaType)); nSeconds = GetMovieDuration(theMovie)/ GetMovieTimeScale(theMovie); printf("Frames per second (assuming that each video sample is of the same length) = %7.2f fps\n", (float) nSamples/nSeconds ); // Get the Image Description Structure and present the values. trackCount = GetMovieTrackCount(theMovie); for(index = 1; index <= trackCount; index++) { Track aTrack = NULL; Media aMedia = NULL; OSType aMediaType; aTrack = GetMovieIndTrack(theMovie, index); DebugAssert(aTrack != NULL); aMedia = GetTrackMedia(aTrack); DebugAssert(aMedia != NULL); anErr = GetMoviesError(); DebugAssert(anErr == noErr); if(anErr != noErr) { printf("Problems with getting trackmedia = %d\n", anErr); return; } GetMediaHandlerDescription(aMedia, &aMediaType, 0, 0); if(aMediaType == VideoMediaType) // We just want to check the video media samples. { SampleDescriptionHandle anImageDesc = NULL; anImageDesc = (SampleDescriptionHandle)NewHandle(sizeof(SampleDescription)); DebugAssert(GetMemErr == noErr); GetMediaSampleDescription(aMedia, 1, anImageDesc); anErr = GetMoviesError(); DebugAssert(anErr == noErr); MoveHHi((Handle)anImageDesc); HLock((Handle)anImageDesc); // Really would not need to, but printf (don't trust that one // due to the MetroWerks Sioux environment). if(anErr != noErr) { DisposeHandle((Handle)anImageDesc); continue; } // OK, we have the Image Description, now present the values (see IM:QuickTime, page 3-50 for more // information about the ImageDescription structure). printf("The video track has a pixel depth of %d.\n", (*(ImageDescriptionHandle)anImageDesc)->depth); // Get the image description height and width values, test if these are multiple of 4 (if not there's a performance penalty). { long rest; printf("The video track has a source image height of %d.\n", (*(ImageDescriptionHandle)anImageDesc)->height); rest = (*(ImageDescriptionHandle)anImageDesc)->height % 4; if (rest != 0) printf("NOTE! The source image height is not a multiple of 4, this means a performance hit.\n"); printf("The video track has a source image width of %d.\n", (*(ImageDescriptionHandle)anImageDesc)->width); rest = (*(ImageDescriptionHandle)anImageDesc)->width % 4; if (rest != 0) printf("NOTE! The source image width is not a multiple of 4, this means a performance hit.\n"); } printf("The video track has a horizontal resolution of %ld.\n", Fix2Long( (*(ImageDescriptionHandle)anImageDesc)->hRes) ); printf("The video track has a vertical resolution of %ld.\n", Fix2Long( (*(ImageDescriptionHandle)anImageDesc)->vRes) ); printf("The codec used to compress the video samples: %s\n", p2cstr( (*(ImageDescriptionHandle)anImageDesc)->name) ); printf("Note that this is the codec for the first video sample, the video samples in the movie might have various codecs used...\n"); { Byte *bp = (Byte *)&(*(ImageDescriptionHandle)anImageDesc)->vendor; printf("The video track was compressed by codec provided by '%c%c%c%c'.\n", bp[0], bp[1], bp[2], bp[3]); } printf("The temporal compression setting is %ld\n", (*(ImageDescriptionHandle)anImageDesc)->temporalQuality); printf("The spatial compression setting is %ld\n", (*(ImageDescriptionHandle)anImageDesc)->spatialQuality); printf("The image description structure is %ld bytes in size.\n", (*(ImageDescriptionHandle)anImageDesc)->idSize); DisposeHandle((Handle)anImageDesc); } } } // ______________________________________________________________________ void ShowMovieSoundInfo(Movie theMovie) { Str255 tmpStr; short trackCount, index; OSErr anErr = noErr; DebugAssert(aMovie != NULL); GetWTitle(FrontWindow(), tmpStr); printf("\nSound Media Information for %s:\n", p2cstr(tmpStr)); #ifdef THIS_WILL_TAKE_LONG printf("The movie has %d sound samples (samples)\n", QTUCountMediaSamples(theMovie, SoundMediaType)); #endif // THIS_WILL_TAKE_LONG // Get the sound description handle and munch it: trackCount = GetMovieTrackCount(theMovie); for(index = 1; index <= trackCount; index++) { Track aTrack = NULL; Media aMedia = NULL; OSType aMediaType; aTrack = GetMovieIndTrack(theMovie, index); DebugAssert(aTrack != NULL); aMedia = GetTrackMedia(aTrack); DebugAssert(aMedia != NULL); anErr = GetMoviesError(); DebugAssert(anErr == noErr); if(anErr != noErr) { printf("Problems with getting trackmedia = %d\n", anErr); return; } GetMediaHandlerDescription(aMedia, &aMediaType, 0, 0); if(aMediaType == SoundMediaType) // We just want to check out the sound description handles. { SampleDescriptionHandle aDesc = NULL; aDesc = (SampleDescriptionHandle)NewHandle(sizeof(SampleDescription)); DebugAssert(GetMemErr() == noErr); GetMediaSampleDescription(aMedia, 1, aDesc); anErr = GetMoviesError(); DebugAssert(anErr == noErr); MoveHHi((Handle)aDesc); HLock((Handle)aDesc); // Really would not need to, but printf (don't trust that one // due to the MetroWerks Sioux environment). if(anErr != noErr) { DisposeHandle((Handle)aDesc); continue; } // OK, we have the sound description handle now, present the values printf("The sound track rate is %d Hz.\n", (*(SoundDescriptionHandle)aDesc)->sampleRate >> 16); { long soundRate = (*(SoundDescriptionHandle)aDesc)->sampleRate >> 16; if (soundRate < 30000) if( (soundRate != 22050) && (soundRate != 11025) ) printf("NOTE! The movie has a sound rate that will maybe cause performance problems with certain PC sound boards. If possible use 22050 or 11025 kHz instead\n"); } printf("The sound track size is %d bit.\n", (*(SoundDescriptionHandle)aDesc)->sampleSize); printf("The sound track has %d channel(s).\n", (*(SoundDescriptionHandle)aDesc)->numChannels); { Byte *bp = (Byte *)&(*(SoundDescriptionHandle)aDesc)->dataFormat; printf("The sound track has the '%c%c%c%c' format.\n", bp[0], bp[1], bp[2], bp[3]); } printf("The sound description structure is %ld bytes in size.\n", (*(SoundDescriptionHandle)aDesc)->descSize); } } } // ______________________________________________________________________ // This is a variation function of the QTUCountMediaSamples one, we want to figure out how // many key frames we have in the movie. pascal long QTUCountKeySamples(Movie theMovie, OSType theMediaType) { long numFrames = 0; short flags = nextTimeEdgeOK + nextTimeSyncSample; TimeValue aDuration = 0; TimeValue theTime = 0; GetMovieNextInterestingTime(theMovie, flags, 1, &theMediaType, theTime, 0, &theTime, &aDuration); if(theTime == -1) return numFrames; flags = nextTimeSyncSample; // Don't include the nudge after the first interesting time. while(theTime != -1) // When the returned time equals -1, then there were no more interesting times. { numFrames++; GetMovieNextInterestingTime(theMovie, flags, 1, &theMediaType, theTime, 0, &theTime, &aDuration); } return numFrames; }